﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Xml;
using System.ComponentModel;
using System.Diagnostics;
using System.Collections.ObjectModel;
using for7raid.vkConnector;

namespace for7raid.vkPlayer
{
    public class MediaItem : DependencyObject
    {
        public int ID { get; set; }
        public int Owner { get; set; }
        public string Artist { get; set; }
        public string Title { get; set; }
        public string URL { get; set; }
        public TimeSpan Duration { get; set; }
        public int AlbumId { get; set; }

      
        public string tagArtist
        {
            get { return (string)GetValue(tagArtistProperty); }
            set { SetValue(tagArtistProperty, value); }
        }

        // Using a DependencyProperty as the backing store for tagArtist.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty tagArtistProperty =
            DependencyProperty.Register("tagArtist", typeof(string), typeof(MediaItem), new UIPropertyMetadata(""));



        public string tagTitle
        {
            get { return (string)GetValue(tagTitleProperty); }
            set { SetValue(tagTitleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for tagTitle.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty tagTitleProperty =
            DependencyProperty.Register("tagTitle", typeof(string), typeof(MediaItem), new UIPropertyMetadata(""));



        public string tagAlbum
        {
            get { return (string)GetValue(tagAlbumProperty); }
            set { SetValue(tagAlbumProperty, value); }
        }

        // Using a DependencyProperty as the backing store for tagAlbum.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty tagAlbumProperty =
            DependencyProperty.Register("tagAlbum", typeof(string), typeof(MediaItem), new UIPropertyMetadata(""));



        public string tagYear
        {
            get { return (string)GetValue(tagYearProperty); }
            set { SetValue(tagYearProperty, value); }
        }

        // Using a DependencyProperty as the backing store for tagYear.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty tagYearProperty =
            DependencyProperty.Register("tagYear", typeof(string), typeof(MediaItem), new UIPropertyMetadata(""));


        public string tagComment
        {
            get { return (string)GetValue(tagCommentProperty); }
            set { SetValue(tagCommentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for tagComment.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty tagCommentProperty =
            DependencyProperty.Register("tagComment", typeof(string), typeof(MediaItem), new UIPropertyMetadata(""));



        public string tagGenre
        {
            get { return (string)GetValue(tagGenreProperty); }
            set { SetValue(tagGenreProperty, value); }
        }

        // Using a DependencyProperty as the backing store for tagGenre.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty tagGenreProperty =
            DependencyProperty.Register("tagGenre", typeof(string), typeof(MediaItem), new UIPropertyMetadata(""));

        
        

        public bool IsCurrent
        {
            get { return (bool)GetValue(IsCurrentProperty); }
            set { SetValue(IsCurrentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsCurrent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsCurrentProperty =
            DependencyProperty.Register("IsCurrent", typeof(bool), typeof(MediaItem), new UIPropertyMetadata(false));



        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(MediaItem), new UIPropertyMetadata(""));



        public int lyrics_id
        {
            get { return (int)GetValue(lyrics_idProperty); }
            set { SetValue(lyrics_idProperty, value); }
        }

        // Using a DependencyProperty as the backing store for lyrics_id.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty lyrics_idProperty =
            DependencyProperty.Register("lyrics_id", typeof(int), typeof(MediaItem), new UIPropertyMetadata(0,
                (d, e) => { /*if ((int)e.NewValue > 0) (d as MediaItem).LoadLirycs();*/ }
                ));



        public MediaItem()
        {

            Text = "";
        }








        public static ObservableCollection<MediaItem> FromResponse(XmlDocument doc, bool isDistinct)
        {
            //var list1 = doc.SelectNodes("/response/audio");
            //foreach (XmlNode i in list1)
            //{
            //    var ID = i["aid"].ParseXmlNodeAsInt();
            //    var Owner = i["owner_id"].ParseXmlNodeAsInt();
            //    var Artist = i["artist"].InnerText.Encode();
            //    var Title = i["title"].InnerText.Encode();
            //    var URL = i["url"].InnerText;
            //    var Duration = TimeSpan.FromSeconds(i["duration"].ParseXmlNodeAsInt());
            //    var lyrics_id = i["lyrics_id"].ParseXmlNodeAsInt();
            //    var AlbumId = i["album"].ParseXmlNodeAsInt();
            //}


            var list = doc.SelectNodes("/response/audio").OfType<XmlNode>().Where(i=>i.HasChildNodes).Select(i => new MediaItem()
            {
                ID = i["aid"].ParseXmlNodeAsInt(),
                Owner = i["owner_id"].ParseXmlNodeAsInt(),
                Artist = i["artist"].InnerText.Encode(),
                Title = i["title"].InnerText.Encode(),
                URL = i["url"].InnerText,
                Duration = TimeSpan.FromSeconds(i["duration"].ParseXmlNodeAsInt()),
                lyrics_id = i["lyrics_id"].ParseXmlNodeAsInt(),
                AlbumId = i["album"].ParseXmlNodeAsInt()
            });
            if (isDistinct)
                return new ObservableCollection<MediaItem>(list.Distinct(new Comparator()));
            else
                return new ObservableCollection<MediaItem>(list);
        }

        public static ObservableCollection<MediaItem> FromResponse(XmlDocument doc)
        {
            return FromResponse(doc, false);
        }

        public void Save()
        {
            Audio.Edit(ID, Owner, Artist, Title, Text).ExecAsync(null);
        }

        
        public void LoadLirycs()
        {

            try
            {


                Audio.GetLyrics(lyrics_id).ExecAsync(
                    doc =>
                    {
                        Text = doc.SelectSingleNode("/response/lyrics/text").InnerText.Encode();
                    });
            }
            catch (Exception ex)
            {
                //ничего не будем говрить - это как бы фоновая загрузка текста

            }

        }



        public void AddToMe()
        {
            try
            {

                Audio.AddAudio(ID, Owner).Exec();

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
        }

        public bool Delete()
        {
            try
            {

                Audio.Delete(ID, Owner).Exec();
                return true;

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
                return false;
            }
        }

        public void UpdateMP3TagAsync()
        {
            for7raid.Control.HTTPUtil.GetLast128BytesAsync(URL, fs =>
            {

                using (fs)
                {

                    MusicID3Tag tag = new MusicID3Tag();
                    fs.Read(tag.TAGID, 0, tag.TAGID.Length);
                    fs.Read(tag.Title, 0, tag.Title.Length);
                    fs.Read(tag.Artist, 0, tag.Artist.Length);
                    fs.Read(tag.Album, 0, tag.Album.Length);
                    fs.Read(tag.Year, 0, tag.Year.Length);
                    fs.Read(tag.Comment, 0, tag.Comment.Length);
                    fs.Read(tag.Genre, 0, tag.Genre.Length);
                    string theTAGID = Encoding.Default.GetString(tag.TAGID);

                    if (theTAGID.Equals("TAG"))
                    {
                        tagTitle = Encoding.Default.GetString(tag.Title).Replace("\0", "");
                        tagArtist = Encoding.Default.GetString(tag.Artist).Replace("\0", "");
                        tagAlbum = Encoding.Default.GetString(tag.Album).Replace("\0", "");
                        tagYear = Encoding.Default.GetString(tag.Year).Replace("\0", "");
                        tagComment = Encoding.Default.GetString(tag.Comment).Replace("\0", "");
                        tagGenre = Encoding.Default.GetString(tag.Genre).Replace("\0", "");

                    }

                }
            });
        }


        class MusicID3Tag
        {

            public byte[] TAGID = new byte[3];      //  3
            public byte[] Title = new byte[30];     //  30
            public byte[] Artist = new byte[30];    //  30 
            public byte[] Album = new byte[30];     //  30 
            public byte[] Year = new byte[4];       //  4 
            public byte[] Comment = new byte[30];   //  30 
            public byte[] Genre = new byte[1];      //  1

        }
        public class Comparator : IEqualityComparer<MediaItem>
        {


            #region Члены IEqualityComparer<MediaItem>

            public bool Equals(MediaItem x, MediaItem y)
            {
                return (x.Artist + x.Title).Replace(" ", "").Equals((y.Artist + y.Title).Replace(" ", ""), StringComparison.InvariantCultureIgnoreCase);
            }

            public int GetHashCode(MediaItem obj)
            {
                return 1;
            }

            #endregion
        }
    }
}
